package service

import (
	"bloggo/dto"
	"bloggo/structs"
	"context"
	"errors"
	"fmt"
	"gitee.com/chunanyong/logger"
	"gitee.com/chunanyong/zorm"
	"github.com/gin-gonic/gin"
)

//SaveTbCommentStruct 保存
//如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
//如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
//如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
//但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func SaveTbCommentStruct(ctx context.Context, tbcommentstruct *structs.TbCommentStruct) error {

	// tbcommentstruct对象指针不能为空
	if tbcommentstruct == nil {
		return errors.New("tbcommentstruct对象指针不能为空")
	}
	//匿名函数return的error如果不为nil,事务就会回滚
	_, errSaveTbCommentStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始

		_, errSaveTbCommentStruct := zorm.Insert(ctx, tbcommentstruct)

		if errSaveTbCommentStruct != nil {
			return nil, errSaveTbCommentStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errSaveTbCommentStruct != nil {
		errSaveTbCommentStruct := fmt.Errorf("service.SaveTbCommentStruct错误:%w", errSaveTbCommentStruct)
		logger.Error(errSaveTbCommentStruct)
		return errSaveTbCommentStruct
	}

	return nil
}

//UpdateTbCommentStruct 更新
//如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
//如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
//如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
//但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func UpdateTbCommentStruct(ctx context.Context, tbcommentstruct *structs.TbCommentStruct) error {

	// tbcommentstruct对象指针或主键Id不能为空
	if tbcommentstruct == nil || (tbcommentstruct.Id) < 1 {
		return errors.New("tbcommentstruct对象指针或主键Id不能为空")
	}

	//匿名函数return的error如果不为nil,事务就会回滚
	_, errUpdateTbCommentStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		_, errUpdateTbCommentStruct := zorm.Update(ctx, tbcommentstruct)

		if errUpdateTbCommentStruct != nil {
			return nil, errUpdateTbCommentStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errUpdateTbCommentStruct != nil {
		errUpdateTbCommentStruct := fmt.Errorf("service.UpdateTbCommentStruct错误:%w", errUpdateTbCommentStruct)
		logger.Error(errUpdateTbCommentStruct)
		return errUpdateTbCommentStruct
	}

	return nil
}

//UpdateNotZeroTbCommentStruct 更新
//如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
//如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
//如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
//但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func UpdateNotZeroTbCommentStruct(ctx context.Context, tbcommentstruct *structs.TbCommentStruct) error {

	// tbcommentstruct对象指针或主键Id不能为空
	if tbcommentstruct == nil || (tbcommentstruct.Id) < 1 {
		return errors.New("tbcommentstruct对象指针或主键Id不能为空")
	}

	//匿名函数return的error如果不为nil,事务就会回滚
	_, errUpdateTbCommentStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		_, errUpdateTbCommentStruct := zorm.UpdateNotZeroValue(ctx, tbcommentstruct)

		if errUpdateTbCommentStruct != nil {
			return nil, errUpdateTbCommentStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errUpdateTbCommentStruct != nil {
		errUpdateTbCommentStruct := fmt.Errorf("service.UpdateNotZeroTbCommentStruct错误:%w", errUpdateTbCommentStruct)
		logger.Error(errUpdateTbCommentStruct)
		return errUpdateTbCommentStruct
	}

	return nil
}

//DeleteTbCommentStructById 根据Id删除
//如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
//如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
//如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
//但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func DeleteTbCommentStructById(ctx context.Context, id string) error {

	//id不能为空
	if len(id) < 1 {
		return errors.New("id不能为空")
	}

	//匿名函数return的error如果不为nil,事务就会回滚
	_, errDeleteTbCommentStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		finder := zorm.NewDeleteFinder(structs.TbCommentStructTableName).Append(" WHERE id=?", id)
		_, errDeleteTbCommentStruct := zorm.UpdateFinder(ctx, finder)

		if errDeleteTbCommentStruct != nil {
			return nil, errDeleteTbCommentStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errDeleteTbCommentStruct != nil {
		errDeleteTbCommentStruct := fmt.Errorf("service.DeleteTbCommentStruct错误:%w", errDeleteTbCommentStruct)
		logger.Error(errDeleteTbCommentStruct)
		return errDeleteTbCommentStruct
	}

	return nil
}

//FindTbCommentStructById 根据Id查询信息
//ctx中如果没有dbConnection,则会使用默认的datasource进行无事务查询
func FindTbCommentStructById(ctx context.Context, id string) (*structs.TbCommentStruct, error) {
	//id不能为空
	if len(id) < 1 {
		return nil, errors.New("id不能为空")
	}

	//根据Id查询
	finder := zorm.NewSelectFinder(structs.TbCommentStructTableName).Append(" WHERE id=?", id)
	tbcommentstruct := structs.TbCommentStruct{}
	has, errFindTbCommentStructById := zorm.QueryRow(ctx, finder, &tbcommentstruct)

	//记录错误
	if errFindTbCommentStructById != nil {
		errFindTbCommentStructById := fmt.Errorf("service.FindTbCommentStructById错误:%w", errFindTbCommentStructById)
		logger.Error(errFindTbCommentStructById)
		return nil, errFindTbCommentStructById
	}

	if !has {
		return nil, nil
	}

	return &tbcommentstruct, nil

}

//FindTbCommentStructList 根据Finder查询列表
//ctx中如果没有dbConnection,则会使用默认的datasource进行无事务查询
func FindTbCommentStructList(ctx context.Context, finder *zorm.Finder, page *zorm.Page) ([]structs.TbCommentStruct, error) {

	//finder不能为空
	if finder == nil {
		return nil, errors.New("finder不能为空")
	}

	tbcommentstructList := make([]structs.TbCommentStruct, 0)
	errFindTbCommentStructList := zorm.Query(ctx, finder, &tbcommentstructList, page)

	//记录错误
	if errFindTbCommentStructList != nil {
		errFindTbCommentStructList := fmt.Errorf("service.FindTbCommentStructList错误:%w", errFindTbCommentStructList)
		logger.Error(errFindTbCommentStructList)
		return nil, errFindTbCommentStructList
	}

	return tbcommentstructList, nil
}

func FindReplyDTO(c *gin.Context, ids []int, replyList *[]dto.ReplyDTO, page *zorm.Page) error {
	subFinder := zorm.NewFinder().Append("SELECT")
	subFinder.Append("a.id,a.parent_id ,a.user_id,b.nickname,b.avatar,b.web_site,a.reply_user_id,c.nickname,c.avatar,c.web_site,a.comment_content,a.create_time")
	subFinder.Append("FROM").Append(structs.TbCommentStructTableName).Append("a")
	subFinder.Append("LEFT JOIN").Append(structs.TbUserInfoStructTableName).Append("b").Append("ON a.user_id = b.id")
	subFinder.Append("LEFT JOIN").Append(structs.TbUserInfoStructTableName).Append("c").Append("ON a.reply_user_id = c.id")
	subFinder.Append("WHERE parent_id IN (?) ORDER BY a.id ASC", ids)
	return zorm.Query(c, subFinder, replyList, page)
}
